//
//  ZBAudioRecorder.m
//  ZBUtility
//
//  Created by xzb on 2018/2/28.
//

#import "ZBAudioRecorder.h"
#import <AVFoundation/AVFoundation.h>

#define PATH_RECFILE [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0] stringByAppendingString:@"/rec.caf"]

@interface ZBAudioRecorder () <AVAudioRecorderDelegate>

@property (nonatomic, strong) AVAudioRecorder *recorder;

@property (nonatomic, strong) NSTimer *timer;

@property (nonatomic, strong) void (^volumeChangedBlock)(CGFloat valume);
@property (nonatomic, strong) void (^completeBlock)(NSString *path, CGFloat time);
@property (nonatomic, strong) void (^cancelBlock)(void);

@end

@implementation ZBAudioRecorder

+ (ZBAudioRecorder *)sharedRecorder
{
    static dispatch_once_t once;
    static ZBAudioRecorder *audioRecorder;
    dispatch_once(&once, ^{
        audioRecorder = [[ZBAudioRecorder alloc] init];
    });
    return audioRecorder;
}

- (void)startRecordingWithVolumeChangedBlock:(void (^)(CGFloat volume))volumeChanged
                               completeBlock:(void (^)(NSString *path, CGFloat time))complete
                                 cancelBlock:(void (^)(void))cancel;
{
    self.volumeChangedBlock = volumeChanged;
    self.completeBlock = complete;
    self.cancelBlock = cancel;
    if ([[NSFileManager defaultManager] fileExistsAtPath:PATH_RECFILE]) {
        [[NSFileManager defaultManager] removeItemAtPath:PATH_RECFILE error:nil];
    }
    [self.recorder prepareToRecord];
    [self.recorder record];
    
    if (self.timer && self.timer.isValid) {
        [self.timer invalidate];
    }
    __weak typeof(self) weakSelf = self;
    if (@available(iOS 10.0, *)) {
        self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 repeats:YES block:^(NSTimer * _Nonnull timer) {
            [weakSelf.recorder updateMeters];
            float peakPower = pow(10, (0.05 * [weakSelf.recorder peakPowerForChannel:0]));
            if (weakSelf && weakSelf.volumeChangedBlock) {
                weakSelf.volumeChangedBlock(peakPower);
            }
        }];
    } else {
        [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timerSelector) userInfo:nil repeats:YES];
    }
}

- (void)timerSelector
{
    [self.recorder updateMeters];
    float peakPower = pow(10, (0.05 * [self.recorder peakPowerForChannel:0]));
    if (self && self.volumeChangedBlock) {
        self.volumeChangedBlock(peakPower);
    }
}

- (void)stopRecording
{
    [self.timer invalidate];
    CGFloat time = self.recorder.currentTime;
    [self.recorder stop];
    if (self.completeBlock) {
        self.completeBlock(PATH_RECFILE, time);
        self.completeBlock = nil;
    }
}

- (void)cancelRecording
{
    [self.timer invalidate];
    [self.recorder stop];
    if (self.cancelBlock) {
        self.cancelBlock();
        self.cancelBlock = nil;
    }
}

#pragma mark - # Delegate
//MARK: AVAudioRecorderDelegate
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag {
    if (flag) {
        //        Log(@"录音成功");
    }
}

#pragma mark - # Getter
- (AVAudioRecorder *)recorder
{
    if (_recorder == nil) {
        AVAudioSession *session = [AVAudioSession sharedInstance];
        NSError *sessionError;
        [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
        
        if(session == nil){
            Log(@"Error creating session: %@", [sessionError description]);
            return nil;
        }
        else {
            [session setActive:YES error:nil];
        }
        
        // 设置录音的一些参数
        NSMutableDictionary *setting = [NSMutableDictionary dictionary];
        setting[AVFormatIDKey] = @(kAudioFormatAppleIMA4);              // 音频格式
        setting[AVSampleRateKey] = @(44100);                            // 录音采样率(Hz)
        setting[AVNumberOfChannelsKey] = @(1);                          // 音频通道数 1 或 2
        setting[AVLinearPCMBitDepthKey] = @(8);                         // 线性音频的位深度
        setting[AVEncoderAudioQualityKey] = [NSNumber numberWithInt:AVAudioQualityHigh];        //录音的质量
        
        _recorder = [[AVAudioRecorder alloc] initWithURL:[NSURL fileURLWithPath:self.recFilePath] settings:setting error:NULL];
        _recorder.delegate = self;
        _recorder.meteringEnabled = YES;
    }
    return _recorder;
}

- (NSString *)recFilePath
{
    return PATH_RECFILE;
}

@end
